package zcj.succ.limitdownload.aspect;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class DownloadAspect {
   @Resource
   private RedisTemplate<String,String>redisTemplate;

    @Pointcut("@annotation(zcj.succ.limitdownload.aspect.PreventRepeatCommit)")
    public void preRepeatCommit(){}

    @Before("preRepeatCommit()")
    public void beforeDirect(JoinPoint joinPoint){
        //获取request对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //拿到token
        String token = request.getHeader("token");
        if(token==null){
            //throw new RuntimeException("请先登录!");
            //测试用
            token ="7758258";
        }
        //获得方法签名
        MethodSignature methodSignatures = (MethodSignature)joinPoint.getSignature();
        //获得方法对象
        Method method = methodSignatures.getMethod();
        //判断是否存在防重复提交注解
        if(method.isAnnotationPresent(PreventRepeatCommit.class)){
            //获取注解对象
            PreventRepeatCommit prc = method.getAnnotation(PreventRepeatCommit.class);
            //根据token 获取value
            String value = redisTemplate.opsForValue().get(token);
            //如果有值说明重复提交需要限流
            if(value!=null){
                throw new RuntimeException(prc.message());
            }
            //取出注解中的值 设置过期key
            long duration = prc.duration();
            TimeUnit unit = prc.unit();
            redisTemplate.opsForValue().set(token,"",duration,unit);
        }
    }
}
